package org.magnerfuller.imtoolkit.server.service;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;

import org.magnerfuller.imtoolkit.server.status.ServerStatus;

public class ManagementConsoleService extends BufferedServiceBackend {
  
  public static final String moduleName = "console";

  private Map<String, Method> commandToMethodTable;
  
  private static final String COMMAND_PREFIX = "_command_";
  
  private static final String DEFAULT_METHOD_NAME = "_command_help";
  
  private static Method DEFAULT_METHOD = null;
  
  private static final String DEFAULT_MESSAGE = "Unrecognized command";
  
  private static final String COMMAND_FAIL_MESSAGE = "Recognized command failed";
  
  private static final String WELCOME_MESSAGE = "Welcome to the IM-Toolkit Server Management Console";
  
  public ManagementConsoleService() throws IOException {
    super();
    _initCommandToMethodTable();
  }
  
  public void initialize(Map<String, String> params) {
    
  }
  
  private void _initCommandToMethodTable() {
    commandToMethodTable = new HashMap<String, Method>();
    
    Method[] methods = ManagementConsoleService.class.getMethods();
    
    for(int i = 0; i < methods.length; i++) {
      String rawName = methods[i].getName();
      
      if(rawName.startsWith(COMMAND_PREFIX)) {
        System.err.print("Adding method " + rawName);
        String commandName = 
          rawName.substring(COMMAND_PREFIX.length(), rawName.length());
        System.err.println(" as command " + commandName);
        commandToMethodTable.put(commandName, methods[i]);
      }
      
      if(rawName.equals(DEFAULT_METHOD_NAME)) {
        DEFAULT_METHOD = methods[i];
      }
    }
    
  }
  
  private Method _lookupCommandMethod(String command) {
    Method method = commandToMethodTable.get(command);
    
    if(method == null) {
      method = DEFAULT_METHOD;
    }
    
    return method;
  }
  
  public String getModuleName() {
    return "console";
  }
  
  public void run() {
    String input;
    try {
      writer.println(WELCOME_MESSAGE);
      writer.flush();
      
      while((input = reader.readLine()) != null && !input.equals("")) {
        StringTokenizer tokens = new StringTokenizer(input);
        
        if(tokens.hasMoreTokens()) {
          String command = tokens.nextToken();
          
          Method method = this._lookupCommandMethod(command);
          
          if(method == null) {
            System.err.println("ManagementConsoleService::run: No default command set!");
            writer.println(DEFAULT_MESSAGE);
          }
          else {
            try {
              method.invoke(this, tokens);
            } catch(IllegalAccessException e) {
              writer.println(COMMAND_FAIL_MESSAGE);
              System.err.println("ManagementConsoleService::run: " + e);
              System.err.println("FIXME");
            } catch(InvocationTargetException e) {
              writer.println(COMMAND_FAIL_MESSAGE);
              System.err.println("ManagementConsoleService::run: " + e);
              System.err.println("FIXME");
            }
              
          }
        }
      }
      
      reader.close();
      writer.close();
      
    } catch(IOException e) {
      System.err.println("ManagementConsoleService::run: " + e);
      e.printStackTrace();
    }

  }
  
  public void _command_help(StringTokenizer restOfTokens) {
    writer.println("Help: Not yet implemented");
    writer.flush();
  }
  
  public void _command_list(StringTokenizer restOfTokens) {
    if(restOfTokens.hasMoreTokens()) {
      String listWhat = restOfTokens.nextToken();
      
      if(listWhat.equals("sessions")) {
        Vector<String> sessionNames = ServerStatus.getInstance().getSessionNames();
        
        int i = 1;
        for(String name : sessionNames) {
          writer.printf("[ %8d ]  " + name, i);
          writer.println();
          
          i++;
        }
      }
      else {
        writer.println(listWhat + " is an invalid argument to list.");
      }
    }
    else {
      writer.println("List what?");
      writer.flush();
    }
    
    writer.flush();
  }
  
}
